package com.fjwt.gz.province.changchun.encrypt;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.TreeMap;

/**
 * 签名工具
 *
 * @author Lee
 **/
public class SignatureUtil {

    private static final Logger logger = LoggerFactory.getLogger(SignatureUtil.class);
    private static final String HMAC_SHA256 = "HmacSHA256";
    private static final String UTF_8 = "UTF-8";

    // 1分钟的时间窗口
    private static final long TIME_WINDOW_MS = 1 * 60 * 1000;
    private static final String TIME_KEY = "auth-timestamp";

    /**
     * 生成签名
     *
     * @param params 参数集合
     * @param secretKey 密钥
     * @return 签名字符串
     * @throws NoSuchAlgorithmException 如果算法不支持
     * @throws InvalidKeyException 如果密钥无效
     */
    public static String generateSignature(Map<String, String> params, String secretKey) throws NoSuchAlgorithmException, InvalidKeyException {
        // 使用TreeMap确保参数按字典顺序排序
        TreeMap<String, String> sortedParams = new TreeMap<>(params);
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        // 去掉最后一个&
        String stringToSign = sb.length() > 0 ? sb.substring(0, sb.length() - 1) : "";
//        String stringToSign = sb.substring(0, sb.length() - 1);

//        long timestamp = System.currentTimeMillis();
//        stringToSign += "&" + TIME_KEY + "=" + timestamp;

        logger.debug("String to sign: {}", stringToSign);

        Mac mac = Mac.getInstance(HMAC_SHA256);
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), HMAC_SHA256);
        mac.init(secretKeySpec);
        byte[] hash = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));

        return bytesToHex(hash);
    }

    /**
     * 将字节数组转换为十六进制字符串
     *
     * @param bytes 字节数组
     * @return 十六进制字符串
     */
    private static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xFF & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }

    /**
     * 验证签名
     *
     * @param params 参数集合
     * @param secretKey 密钥
     * @param signature 待验证的签名
     * @return 签名是否有效
     * @throws NoSuchAlgorithmException 如果算法不支持
     * @throws InvalidKeyException 如果密钥无效
     */
    public static boolean verifySignature(Map<String, String> params, String secretKey, String signature) throws NoSuchAlgorithmException, InvalidKeyException {
        if (signature == null) {
            return false;
        }

        params.remove("signature");

//        String timestampStr = params.get(TIME_KEY);
//        if (timestampstr == null) {
//            return false;
//        }

//        long timestamp = Long.parseLong(timestampstr);

//        long currentTime = System.currentTimeMillis();
//        if (Math.abs(currentTime - timestamp) > TIME_WINDOW_MS) {
//            return false;
//        }

//        if (params.size() == 0) {
//            return secretKey.equals(signature);
//        }

        String generatedSignature = generateSignature(params, secretKey);
        logger.debug("Generated signature: {}, Provided signature: {}", generatedSignature, signature);
        return generatedSignature.equals(signature);
    }
}